package com.huaxin.common.message.util;

import android.content.Context;
import android.os.AsyncTask;

import com.huaxin.common.RequestApi;
import com.huaxin.common.model.BaseBean;
import com.huaxin.common.tools.Log;
import com.huaxin.common.tools.ProgressListener;

import java.io.File;
import java.io.IOException;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;

/**
 * 异步AsyncTask+HttpClient上传文件,支持多文件上传,并显示上传进度
 */
public class UploadTask extends AsyncTask<String, Integer, String> {

    private final static String TAG = "UploadTask";

    public interface CallBack {
        /**
         * if return true will show dialog for upload!
         *
         * @param action
         * @return
         */
        boolean onStart(String action);

        void onSuccess(String action);

        void onError(String action, String error);

        void onProgress(String action, int percent);
    }

    UploadDialog dialog;
    private BaseBean bean;
    private long totalSize;
    private long readSize;
    private Context context;
    private CallBack back;

    public UploadTask(Context context, CallBack back, BaseBean bean) {
        this.context = context;
        this.bean = bean;
        this.back = back;
    }

    @Override
    protected void onPreExecute() {// 执行前的初始化
        if (!back.onStart(bean.action)) {
            dialog = new UploadDialog(context, "请稍等...");
            dialog.setCancelable(false);
            dialog.show();
        } else {
            dialog = null;
        }
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... params) {// 执行任务
//        final MultipartEntityBuilder builder = MultipartEntityBuilder.create();
//        builder.setCharset(Charset.forName(HTTP.UTF_8));// 设置请求的编码格式
//        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);// 设置浏览器兼容模式
//        final ArrayMap<String, File> files = bean.getFiles();
//        for (String name : files.keySet()) {
//            // FileBody fileBody = new FileBody(file);//把文件转换成流对象FileBody
//            // builder.addPart("file"+count, fileBody);
//            builder.addBinaryBody(name, files.get(name), ContentType.create("multipart/form-data"), files.get(name).getName());
//        }
//        final ArrayMap<String, String> beanParams = bean.getParams();
//        // 设置请求参数
//        for (String key : beanParams.keySet()) {
//            String value = beanParams.get(key);
////            try {
////                // s = new String(entry.getValue().toString().getBytes("GBK"),
////                // "UTF-8");
////                value = new String(value.getBytes("UTF-8"));
////                value = URLEncoder.encode(value, "UTF-8");
////            } catch (UnsupportedEncodingException e) {
////                value = value.getValue();
////            }
//            builder.addTextBody(key, value);
//        }
//        final HttpEntity entity = builder.build();// 生成 HTTP POST 实体
//        Log.i(TAG, "doInBackground:" + entity.getContentLength());
//        totalSize = entity.getContentLength();// 获取上传文件的大小
//        ProgressOutHttpEntity progressHttpEntity = new ProgressOutHttpEntity(
//                entity, new ProgressOutHttpEntity.ProgressListener() {
//            @Override
//            public void transferred(long transferedBytes) {
//                publishProgress((int) (100 * transferedBytes / totalSize));// 更新进度
//            }
//        });
        return uploadFile(bean);
    }

    @Override
    protected void onProgressUpdate(Integer... values) {// 执行进度
        if (dialog != null) {
            dialog.setProgress(values[0]);// 更新进度条
        }
        back.onProgress(bean.action, values[0]);
        super.onProgressUpdate(values);
    }

    @Override
    protected void onPostExecute(String result) {// 执行结果
        Log.i(TAG, result);
        if (dialog != null) {
            dialog.dismiss();
        }
        super.onPostExecute(result);
    }

    /**
     * 向服务器上传文件
     */
    public String uploadFile(BaseBean bean) {
        final MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        totalSize = 0;
        readSize = 0;
        for (String key : bean.getFiles().keySet()) {
            final File file = bean.getFiles().get(key);
            totalSize += file.length();
            builder.addFormDataPart(key, file.getName(), createCustomRequestBody(MultipartBody.FORM, file, new ProgressListener() {
                @Override
                public void onProgress(long totalBytes, long remainingBytes, boolean done) {
                    readSize += totalBytes - remainingBytes;
                    publishProgress((int) (100 * readSize / totalSize));
                }
            }));
        }

        Retrofit retrofit = new Retrofit.Builder().baseUrl(bean.getURL()).build();
        RequestApi requestApi = retrofit.create(RequestApi.class);
        Call<String> call = requestApi.upload4("upload files", builder.build());
        try {
            Response<String> response = call.execute();
            if (response.isSuccessful()) {
                back.onSuccess(bean.action);
                return response.body();
            } else {
                back.onError(bean.action, response.errorBody().string());
                return response.errorBody().toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
            back.onError(bean.action, "上传异常!");
            return "上传异常!";
        }
    }

    public static RequestBody createCustomRequestBody(final MediaType contentType, final File file, final ProgressListener listener) {
        return new RequestBody() {
            @Override
            public MediaType contentType() {
                return contentType;
            }

            @Override
            public long contentLength() {
                return file.length();
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                Source source;
                try {
                    source = Okio.source(file);
                    //sink.writeAll(source);
                    Buffer buf = new Buffer();
                    Long remaining = contentLength();
                    for (long readCount; (readCount = source.read(buf, 2048)) != -1; ) {
                        sink.write(buf, readCount);
                        listener.onProgress(contentLength(), remaining -= readCount, remaining == 0);

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
    }
}
